const dayjs = require('dayjs');
/**
 * 研发流程状态机单元测试
 */

// 引入状态机
const {
  PROJECT_STATUS,
  ACTIVE_STATE,
  SUB_STATE,
  STATE_EVENTS,
  STATUS_ROLE_PERMISSIONS,
  STATE_TRANSITIONS,
  researchStateMachineStore
} = require('./state_machine_bridge.js');

/**
 * 测试状态机基本功能
 */
async function testStateMachine() {
  console.log('==== 状态机测试开始 ====');
  
  // 模拟项目数据
  const mockProject = {
    _id: 'test-project-001',
    RESEARCH_NAME: '测试项目',
    RESEARCH_STATUS: PROJECT_STATUS.PROJECT_REVIEW,
    RESEARCH_SUB_STATUS: SUB_STATE.DIRECTOR,
    RESEARCH_ACTIVE_STATE: '',
    RESEARCH_ACTIVE_SUB_STATE: ''
  };
  
  // 测试设置项目
  console.log('测试: 设置项目数据');
  researchStateMachineStore.setProject(mockProject);
  console.assert(researchStateMachineStore.project === mockProject, '项目数据未正确设置');
  
  // 测试设置角色
  console.log('测试: 设置用户角色');
  researchStateMachineStore.setCurrentRole('director');
  console.assert(researchStateMachineStore.currentRole === 'director', '角色未正确设置');
  
  // 测试获取可用事件
  console.log('测试: 获取可用事件');
  const events = researchStateMachineStore.getAvailableEvents();
  console.log('可用事件:', events);
  console.assert(Array.isArray(events), '可用事件应该是数组');
  
  // 检查董事长审核状态下的可用事件
  const directorApproveEvent = events.find(e => e.id === STATE_EVENTS.DIRECTOR_APPROVE);
  const directorRejectEvent = events.find(e => e.id === STATE_EVENTS.DIRECTOR_REJECT);
  
  console.assert(directorApproveEvent, '董事长应该有审核通过权限');
  console.assert(directorRejectEvent, '董事长应该有审核拒绝权限');
  
  // 测试状态名称获取
  console.log('测试: 获取状态名称');
  const statusName = researchStateMachineStore.getStatusName(PROJECT_STATUS.PROJECT_REVIEW);
  console.assert(statusName === '项目审核', '状态名称不正确');
  
  // 测试获取活动状态名称
  console.log('测试: 获取活动状态名称');
  const activeStateName = researchStateMachineStore.getActiveStateName(ACTIVE_STATE.HARDWARE);
  console.assert(activeStateName === '硬件', '活动状态名称不正确');
  
  // 测试获取事件名称
  console.log('测试: 获取事件名称');
  const eventName = researchStateMachineStore.getEventName(STATE_EVENTS.DIRECTOR_APPROVE);
  console.assert(eventName === '董事长审核通过', '事件名称不正确');
  
  // 测试状态转换（模拟）
  console.log('测试: 模拟状态转换');
  // 更新项目状态为研发经理审核
  mockProject.RESEARCH_STATUS = PROJECT_STATUS.PROJECT_REVIEW;
  mockProject.RESEARCH_SUB_STATUS = SUB_STATE.RD_MANAGER;
  researchStateMachineStore.setProject(mockProject);
  researchStateMachineStore.setCurrentRole('research_manager');
  
  // 获取研发经理可用事件
  const managerEvents = researchStateMachineStore.getAvailableEvents();
  console.log('研发经理可用事件:', managerEvents);
  
  const managerApproveEvent = managerEvents.find(e => e.id === STATE_EVENTS.MANAGER_APPROVE);
  console.assert(managerApproveEvent, '研发经理应该有审核通过权限');
  
  console.log('==== 状态机测试完成 ====');
}

/**
 * 测试加载流程历史记录
 */
async function testLoadFlowHistory() {
  console.log('==== 流程历史记录测试开始 ====');
  
  // 模拟项目数据
  const mockProject = {
    _id: 'test-project-001',
    RESEARCH_NAME: '测试项目',
    RESEARCH_STATUS: PROJECT_STATUS.PROJECT_REVIEW,
    RESEARCH_SUB_STATUS: SUB_STATE.DIRECTOR,
    RESEARCH_ACTIVE_STATE: '',
    RESEARCH_ACTIVE_SUB_STATE: ''
  };
  
  // 设置项目数据
  researchStateMachineStore.setProject(mockProject);
  
  // 尝试加载流程历史
  try {
    // 这里我们不实际调用云函数，而是模拟历史记录
    // 在实际环境中，应该调用 researchStateMachineStore.loadFlowHistory()
    
    // 模拟流程历史记录
    const mockHistory = [
      {
        _id: 'history-001',
        projectId: 'test-project-001',
        oldStatus: PROJECT_STATUS.PROJECT_REVIEW,
        oldSubStatus: SUB_STATE.RD_MANAGER,
        newStatus: PROJECT_STATUS.PROJECT_REVIEW,
        newSubStatus: SUB_STATE.DIRECTOR,
        eventId: STATE_EVENTS.MANAGER_APPROVE,
        operatorId: 'test-user-001',
        operatorName: '测试用户1',
        operatorRole: 'research_manager',
        createTime: dayjs().valueOf() - 3600000
      },
      {
        _id: 'history-002',
        projectId: 'test-project-001',
        oldStatus: PROJECT_STATUS.PROJECT_REVIEW,
        oldSubStatus: SUB_STATE.DIRECTOR,
        newStatus: PROJECT_STATUS.ACTIVE,
        newSubStatus: '',
        eventId: STATE_EVENTS.DIRECTOR_APPROVE,
        operatorId: 'test-user-002',
        operatorName: '测试用户2',
        operatorRole: 'director',
        createTime: dayjs().valueOf() - 1800000
      }
    ];
    
    // 直接设置历史记录
    researchStateMachineStore.flowHistory = mockHistory;
    
    // 检查历史记录是否设置成功
    console.assert(Array.isArray(researchStateMachineStore.flowHistory), '流程历史记录应该是数组');
    console.assert(researchStateMachineStore.flowHistory.length === 2, '流程历史记录应该有2条');
    
    console.log('历史记录:', researchStateMachineStore.flowHistory);
    
  } catch (error) {
    console.error('测试历史记录失败:', error);
  }
  
  console.log('==== 流程历史记录测试完成 ====');
}

// 测试状态转换（需要mock云函数）
async function testPerformStateTransition() {
  console.log('==== 状态转换测试 ====');
  console.log('注意: 这个测试需要在真实环境中进行，因为它需要调用云函数');
  
  // 此处仅做示例，实际测试需要在APP环境中进行
  // try {
  //   const params = {
  //     projectId: 'test-project-001',
  //     eventId: STATE_EVENTS.MANAGER_APPROVE,
  //     formData: {}
  //   };
  //   const result = await researchStateMachineStore.performStateTransition(params);
  //   console.log('状态转换结果:', result);
  // } catch (error) {
  //   console.error('状态转换测试失败:', error);
  // }
  
  console.log('==== 状态转换测试完成 ====');
}

// 运行所有测试
async function runAllTests() {
  try {
    await testStateMachine();
    await testLoadFlowHistory();
    await testPerformStateTransition();
    
    console.log('所有测试完成!');
  } catch (error) {
    console.error('测试过程中出现错误:', error);
  }
}

// 导出测试函数
module.exports = {
  testStateMachine,
  testLoadFlowHistory,
  testPerformStateTransition,
  runAllTests
}; 